using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using ExtensionToolsLibraries.PublicClasses.ExtensionException;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;
using ModelClassLibraries.Model;

namespace DataOperationClassLibraries;

public class UserOperation(UserManager<ApplicationUser> userManager, IConfiguration configuration)
{
    public async Task<string> RegisterUserAsync(string userName, string ShowName, int role, string password)
    {
        var user = await userManager.FindByNameAsync(userName);
        if (user != null)
        {
            throw new ExceptionWithStatus(System.Net.HttpStatusCode.Conflict, "用户名已经存在");
        }
        user = new ApplicationUser
        {
            UserName = userName,
            ShowName = ShowName
        };
        var result = await userManager.CreateAsync(user, password);
        if (result.Succeeded)
        {
            user = await userManager.FindByNameAsync(userName) ?? throw new ExceptionWithStatus(System.Net.HttpStatusCode.NotFound, "注册失败");
            switch (role)
            {
                case 1:
                    await userManager.AddToRoleAsync(user, "Admin");
                    break;
                case 2:
                    await userManager.AddToRoleAsync(user, "User");
                    break;
                default:
                    throw new ExceptionWithStatus(System.Net.HttpStatusCode.BadRequest, "角色不存在");
            }
            return await GenerateJwtToken(user);
        }
        else
        {
            throw new ExceptionWithStatus(System.Net.HttpStatusCode.BadRequest, "注册失败");
        }

    }

    public async Task<string> LoginUserAsync(string userName, string password)
    {
        var user = await userManager.FindByNameAsync(userName) ?? throw new ExceptionWithStatus(System.Net.HttpStatusCode.NotFound, "用户名不存在");
        if (!await userManager.CheckPasswordAsync(user, password))
        {
            throw new ExceptionWithStatus(System.Net.HttpStatusCode.Unauthorized, "密码错误");
        }
        return await GenerateJwtToken(user);
    }

    private async Task<string> GenerateJwtToken(ApplicationUser user)
    {
        var userRoles = await userManager.GetRolesAsync(user);
        var claims = new List<Claim>
        {
            new(ClaimTypes.NameIdentifier, user.Id.ToString()),
            new(ClaimTypes.Name, user.ShowName!)
        };
        foreach (var role in userRoles)
        {
            claims.Add(new Claim(ClaimTypes.Role, role));
        }

        var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration["Jwt:SecretKey"]!));
        var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
        var expires = DateTime.Now.AddDays(Convert.ToDouble(configuration["Jwt:ExpireDays"]));

        var token = new JwtSecurityToken(
            issuer: configuration["Jwt:Issuer"],
            audience: configuration["Jwt:Audience"],
            claims: claims,
            expires: expires,
            signingCredentials: creds
        );

        return new JwtSecurityTokenHandler().WriteToken(token);
    }
}